package com.leonzhangxf.ioc.i18n;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.nio.charset.StandardCharsets;
import java.util.Locale;

/**
 * The demo of use application-context's internationalization supported by the interface
 * {@link org.springframework.context.MessageSource} design.
 *
 * @author leonzhangxf
 */
@Configuration
@ComponentScan({"com.leonzhangxf.ioc.i18n"})
public class ApplicationContextForInternationalizationStarter {


    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext =
            new AnnotationConfigApplicationContext(ApplicationContextForInternationalizationStarter.class);

        System.out.println(String.format("The default locale is %s.", Locale.getDefault()));

        System.out.println(applicationContext.getMessage("black.message", new Object[]{"leon"},
            "EnableHello World default", null));
        System.out.println(applicationContext.getMessage("white.message", new Object[]{"leon"},
            "EnableHello World default", null));
        System.out.println(applicationContext.getMessage("black.message", new Object[]{"leon"},
            "EnableHello World default", Locale.ENGLISH));
        System.out.println(applicationContext.getMessage("white.message", new Object[]{"leon"},
            "EnableHello World default", Locale.ENGLISH));
        System.out.println(applicationContext.getMessage("black.message", new Object[]{"leon"},
            "EnableHello World default", Locale.SIMPLIFIED_CHINESE));
        System.out.println(applicationContext.getMessage("white.message", new Object[]{"leon"},
            "EnableHello World default", Locale.SIMPLIFIED_CHINESE));

    }

    @Bean("messageSource")
    public ReloadableResourceBundleMessageSource messageSource() {
        ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
        messageSource.setBasenames("white", "black");
        messageSource.setDefaultEncoding(StandardCharsets.UTF_8.name());
        messageSource.setCacheSeconds(120);
        return messageSource;
    }

    /**
     * Get ConfigurableApplicationContext by reflection mechanism.
     * Maybe just for infrastructure code snippet.
     */
    @SuppressWarnings("unchecked")
    private static AnnotationConfigApplicationContext getContextByAnnotationWay()
        throws ClassNotFoundException, NoSuchMethodException, InstantiationException,
        IllegalAccessException, InvocationTargetException {
        ClassLoader classLoader = AnnotationConfigApplicationContext.class.getClassLoader();
        Class<?> appLoadClass =
            classLoader.loadClass("com.leonzhangxf.ioc.i18n.ApplicationContextForInternationalizationStarter");
        if (!(appLoadClass.isAssignableFrom(ApplicationContextForInternationalizationStarter.class))) {
            System.out.println("not assignable from starter.");
            return null;
        }
        Class<ApplicationContextForInternationalizationStarter> starterClass =
            (Class<ApplicationContextForInternationalizationStarter>) appLoadClass;

        Class<?> springClass =
            classLoader.loadClass("org.springframework.context.annotation.AnnotationConfigApplicationContext");
        if (!(springClass.isAssignableFrom(AnnotationConfigApplicationContext.class))) {
            return null;
        }
        Class<AnnotationConfigApplicationContext> starterSpringClass =
            (Class<AnnotationConfigApplicationContext>) springClass;

        Constructor<AnnotationConfigApplicationContext> constructor = starterSpringClass.getConstructor(Class[].class);
        if (null == constructor) {
            System.out.println("Not found constructor.");
            return null;
        }
        Object[] classes = new Object[]{new Class[]{starterClass}};
        return constructor.newInstance(classes);
    }
}
